<template>
  <div class="fabric-history">
    <canvas id="canvas" width="400" height="400" style="border: 1px"></canvas>
    <button :disabled="!canUndo" @click="historyState(stateIndex - 1)">
      撤销
    </button>
    <button :disabled="!canRedo" @click="historyState(stateIndex + 1)">
      恢复
    </button>
  </div>
</template>

<script>
import { fabric } from 'fabric'
export default {
  name: 'History',
  data() {
    return {
      canvas: null,
      isLoadCanvas: false,
      canvasState: [],
      stateIndex: -1,
    }
  },
  mounted() {
    this.canvas = new fabric.Canvas('canvas', {
      backgroundColor: '#f5deb3',
    })
    this.canvas.on('object:modified', this.updateCanvasState)
    this.canvas.on('object:added', this.updateCanvasState)
    this.addObject()
  },
  computed: {
    canUndo() {
      return this.stateIndex > 0
    },
    canRedo() {
      return this.stateIndex < this.canvasState.length - 1
    },
  },
  methods: {
    addObject() {
      const rect = new fabric.Rect({
        left: 100,
        top: 100,
        fill: 'red',
        width: 200,
        height: 200,
      })
      this.canvas.add(rect)
      this.canvas.renderAll()
    },

    updateCanvasState() {
      if (!this.isLoadCanvas) {
        const canvasAsJson = JSON.stringify(this.canvas.toJSON())
        this.canvasState.splice(this.stateIndex + 1)
        this.canvasState.push(canvasAsJson)
        this.stateIndex = this.canvasState.length - 1
      } else {
        this.isLoadCanvas = false
      }
    },

    historyState(index) {
      if (this.canUndo || this.canRedo) {
        this.isLoadCanvas = true
        this.canvas.loadFromJSON(this.canvasState[index], () => {
          this.canvas.renderAll()
          this.stateIndex = index
        })
      }
    },
  },
}
</script>
